<template>
  <draggable
    v-model="fakeItems"
    :group="{ name: dragGroupName }"
    animation="300"
    :class="dragClass"
    style="min-height: 50px; float: left; width: 100%; display: flex; flex-flow: row wrap"
    item-key="id"
    handle=".drag-icon"
    @end="end"
    @start="start"
    @choose="itemChoose"
  >
    <template #item="{ element }">
      <item
        :id="element.id"
        :ref="element.id"
        :key="element.id"
        :attrs="element.attrs"
        :extend-attrs="element.extendAttrs"
        :is-form="element.form"
        :form="form"
        :properties="element.properties"
        :drag-group-name="dragGroupName"
        :children="element.children"
        :type="element.type"
        :item-choose="itemChoose"
        :select-id="selectId"
        :drag-class="dragClass"
        :check-class="checkClass"
        :logic-control="logicControl"
        @select="
          (v) => {
            $emit('select', v)
          }
        "
        @remove="
          (v) => {
            $emit('remove', v)
          }
        "
      />
    </template>
  </draggable>
</template>

<script>
import draggable from 'vuedraggable'
import Item from './item/index.vue'
export default {
  name: 'DynamicDragForm',
  components: { draggable, Item },
  model: {
    prop: 'items',
    event: 'change'
  },
  props: {
    form: Object,
    dragGroupName: String,
    itemChoose: Function,
    selectId: String,
    checkClass: String,
    dragClass: String,
    logicControl: {
      type: Boolean,
      default: true
    },
    items: {
      type: Array,
      default: () => {
        return []
      }
    }
  },
  emits: ['update:items', 'select', 'remove'],
  data() {
    return { fakeItems: JSON.parse(JSON.stringify(this.items)) }
  },
  watch: {
    items: {
      handler: function (val, oldVal) {
        this.fakeItems = JSON.parse(JSON.stringify(this.items))
      },
      deep: true
    }
  },
  methods: {
    start(e) {},
    end() {},
    isShow(properties) {
      if (this.logicControl && properties.ifCondition) {
        // eslint-disable-next-line no-eval
        return eval('(formValue,$hasRole,$hasPermission)=>{return ' + properties.ifCondition + '}')(
          this.form,
          this['$hasRole'],
          this['$hasPermission']
        )
      }
      return true
    },
    getRef(id) {
      return this.$refs[id]
    },
    addItem(item) {
      this.fakeItems.push(item)
    },
    getData(array, filter) {
      if (!array) {
        array = []
      }
      for (let i = 0; i < this.fakeItems.length; i++) {
        this.getRef(this.fakeItems[i].id).getData(array, filter)
      }
      return array
    },
    findItemById(id) {
      var item = this.fakeItems.find((item) => {
        return item.id == id
      })
      if (!item) {
        for (let i = 0; i < this.fakeItems.length; i++) {
          item = this.getRef(this.fakeItems[i].id).findItemById(id)
          if (item) {
            return item
          }
        }
      } else {
        return item
      }
      return null
    },
    findItemByKey(key) {
      var item = this.fakeItems.find((item) => {
        return item.properties.key == key
      })
      if (!item) {
        for (let i = 0; i < this.fakeItems.length; i++) {
          item = this.getRef(this.fakeItems[i].id).findItemByKey(key)
          if (item) {
            const result = JSON.parse(JSON.stringify(item))
            return result
          }
        }
      } else {
        return item
      }
      return null
    },
    findKeyedItems(array) {
      if (!array) {
        array = []
      }
      for (let i = 0; i < this.fakeItems.length; i++) {
        this.getRef(this.fakeItems[i].id).findKeyedItems(array)
      }
      return array
    },
    findQueryableItemHtml(obj, space) {
      if (!obj) {
        obj = { less: [], more: [] }
      }
      for (let i = 0; i < this.fakeItems.length; i++) {
        this.getRef(this.fakeItems[i].id).findQueryableItemHtml(obj, space)
      }
      return obj
    },
    buildHtml(disable, space, filter, modelName) {
      let html = ''
      for (let i = 0; i < this.fakeItems.length; i++) {
        html =
          html +
          this.getRef(this.fakeItems[i].id).buildHtml(disable, space, filter, modelName) +
          '\r\n'
      }
      return html
    },
    removeItemById(id) {
      let index = -1
      this.fakeItems.forEach((item, i) => {
        if (item.id == id) {
          index = i
          return false
        }
      })
      if (index > -1) {
        this.fakeItems.splice(index, 1)
        return true
      } else {
        for (let i = 0; i < this.fakeItems.length; i++) {
          const flag = this.getRef(this.fakeItems[i].id).removeItemById(id)
          if (flag) {
            return flag
          }
        }
      }
      return false
    }
  }
}
</script>
